package com.ruoyi.file.controller;

import com.ruoyi.chat.LongConnection.model.msg.FileMsg;
import com.ruoyi.chat.service.IMinioService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;

import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.file.domain.ClassesFileRole;
import com.ruoyi.file.domain.UserFileInfo;
import com.ruoyi.file.domain.UserFileRole;
import com.ruoyi.file.domain.vo.GetFileVo;
import com.ruoyi.file.service.IClassesFileRoleService;
import com.ruoyi.file.service.IUserFileInfoApiService;
import com.ruoyi.file.service.IUserFileInfoService;
import com.ruoyi.file.service.IUserFileRoleService;
import com.ruoyi.file.util.FileUtil;

import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.StatObjectArgs;
import io.minio.StatObjectResponse;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;

/**
 * 文件上传API Controller
 *
 * @author zhangxiliang
 * @date 2021-10-31
 */
@RestController
@RequestMapping("/file/api")
public class FileApiController extends BaseController {
    @Autowired
    private IUserFileInfoApiService userFileInfoApiService;
    @Autowired
    private IUserFileInfoService userFileInfoService;
    @Autowired
    private IUserFileRoleService userFileRoleService;
    @Autowired
    private IClassesFileRoleService classesFileRoleService;
    @Autowired
    IMinioService minioService;
    @Autowired
    MinioClient minioClient;
    /**
     * 文件上传接口
     * @param files
     * @param username
     * @return 上传结果
     * @throws IOException
     */

    @PostMapping("/upload")
    public AjaxResult upload(MultipartFile[] files , String username ,String range) throws IOException {

        for (MultipartFile file:files) {
            UserFileInfo userFileInfo = new UserFileInfo();
            FileMsg fileMsg = new FileMsg();
            fileMsg.setFileName(file.getOriginalFilename());
            fileMsg.setStream(file.getBytes());
            try {
                String path = minioService.setFile(fileMsg);
                userFileInfo.setFileName(file.getOriginalFilename());
                userFileInfo.setFilePath(path);
                userFileInfo.setFileMime(file.getContentType());
                userFileInfo.setFileSize(file.getSize());
                if(com.ruoyi.common.utils.StringUtils.isNotNull(range))
                    userFileInfo.setFileRange(Integer.parseInt(range));
                else
                    userFileInfo.setFileRange(0);
                userFileInfo.setCreateBy(username);
                FileUtil.transferTo(file, userFileInfo);
                userFileInfoApiService.insertUserFileInfo(userFileInfo);
            } catch (Exception e) {
                e.printStackTrace();
                return AjaxResult.error(500,"服务器出错了");
            }
        }
        return AjaxResult.success("文件上传成功!");
    }

    /**
     * 获取文件信息列表
     * @param getFileVo
     * @return 文件实体列表
     */
    @GetMapping("/list")
    public AjaxResult getList(GetFileVo getFileVo){
        if (getFileVo.getUserId() != null ) {
            List<UserFileInfo> userFileInfos = userFileInfoApiService.selectUserFileInfoList(getFileVo);
            return AjaxResult.success(userFileInfos);
        }
        else
            return AjaxResult.error("未获取到userId,请求失败");
    }

    /**
     * 通过文件Id获取文件信息
     * @param fileId
     * @return 文件信息实体
     */
    @GetMapping("/getById")
    public AjaxResult getFileInfoByFileId(Long fileId){
        return AjaxResult.success(userFileInfoApiService.selectUserFileInfoByFileId(fileId));
    }

    /**
     * 批量删除文件信息
     * @param fileIds
     * @return 删除结果
     */
    @GetMapping("/deleteByList")
    public AjaxResult deletFileInfoByFileIds(Long[] fileIds){
        return toAjax(userFileInfoApiService.deleteUserFileInfoByFileIds(fileIds));
    }

    /**
     * 删除文件信息
     * @param fileId
     * @return 删除结果
     */
    @GetMapping("/delete")
    public AjaxResult deleteFileInfoByFileId(Long fileId){
        return toAjax(userFileInfoApiService.deleteUserFileInfoByFileId(fileId));
    }

    /**
     * 文件下载接口
     * @param fileId
     * @param httpResponse
     */
    @GetMapping("/download")
    public void fileDownload(Long fileId, HttpServletResponse httpResponse){

        UserFileInfo file = userFileInfoApiService.selectUserFileInfoByFileId(fileId);
        String[] path =file.getFilePath().split("/");
        String bucketName = path[0];
        String fileName = path[1];
        InputStream in =  null;
        try {
            StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
            httpResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getFileName(), "UTF-8"));
            httpResponse.setContentType(stat.contentType());
            //文件下载
            in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            IOUtils.copy(in,httpResponse.getOutputStream());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        file.setFileDownload(file.getFileDownload()+1);
        userFileInfoService.updateUserFileInfo(file);
    }

    /**
     * 根据文件ID获取用户文件权限列表
     * @param userFileRole
     * @return 用户文件权限集合
     */
    @GetMapping("/getUserRole")
    public AjaxResult getUserFileRole(UserFileRole userFileRole){
        return AjaxResult.success(userFileRoleService.selectUserFileRoleList(userFileRole));
    }

    /**
     * 根据文件ID获取班级文件权限列表
     * @param classesFileRole
     * @return 班级文件权限集合
     */
    @GetMapping("/getClassesRole")
    public AjaxResult getClassesFileRole(ClassesFileRole classesFileRole){
        return AjaxResult.success(classesFileRoleService.selectClassesFileRoleList(classesFileRole));
    }

    /**
     * 添加用户文件权限
     * @param fileId
     * @param userIds
     * @return
     */
    @PostMapping("/addUserRole")
    public AjaxResult addUserFileRole(Long fileId ,Long[] userIds){
        if(fileId == null)
            return AjaxResult.error("fileID不能为空");
        else if (userIds.length ==0 )
            return AjaxResult.error("userId不能为空");
        else
            userFileRoleService.insertUserFileRoles(fileId,userIds);
        return AjaxResult.success("添加成功");
    }

    /**
     * 添加班级文件权限
     * @param fileId
     * @param classesIds
     * @return
     */
    @PostMapping("/addClassesRole")
    public AjaxResult addClassesFileRole(Long fileId ,Long[] classesIds){
        if(fileId == null)
            return AjaxResult.error("fileID不能为空");
        else if (classesIds.length ==0 )
            return AjaxResult.error("classesIds不能为空");
        else
            classesFileRoleService.insertClassesFileRoles(fileId,classesIds);
        return AjaxResult.success("添加成功");
    }

    /**
     * 删除班级文档权限
     */
    @GetMapping("/deleteClassesRole")
    public AjaxResult deleteClassesRole(Long[] roleIds)
    {
        return toAjax(classesFileRoleService.deleteClassesFileRoleByRoleIds(roleIds));
    }

    /**
     * 删除用户文档权限
     */
    @GetMapping("/deleteUserRole")
    public AjaxResult deleteUserRole(Long[] roleIds)
    {
        return toAjax(userFileRoleService.deleteUserFileRoleByRoleIds(roleIds));
    }
}
